import axios from 'axios'
import { ElMessage, ElMessageBox } from 'element-plus'
import { useUserStore } from '@/stores'
import router from '@/router'
// 创建 axios 实例
const instance = axios.create({
  //后端服务器ip地址
  baseURL: import.meta.env.VITE_APP_BASE_API,
  timeout: 600000
})
// 添加请求拦截器
instance.interceptors.request.use(
  (config) => {
    // config就是和此次请求相关的信息，包含请求地址，方法，参数，头等
    const userStore = useUserStore()
    const { token } = userStore
    // 如果有Token,说明已经登录过,所有的登录后请求头应该添加Token
    if (token) {
      config.headers.Authorization = token
    }
    return config
  },
  (error) => {
    // 对请求错误做些什么
    return Promise.reject(error)
  }
)
// 是否显示重新登录对话框
const relogin = {
  show: false
}
// 添加响应拦截器
instance.interceptors.response.use(
  (response) => {
    // 解构
    const { code, data, msg } = response.data
    if (code !== 200000) {
      // 统一的错误提示
      ElMessage.error(msg)
      // 返回一个失败态的 Promise 实例
      // 拦截器后的接口请求方就会收到错误的Promise实例，即被.catch到
      return Promise.reject(new Error(msg))
    }
    // 否则返回纯粹的 data 数据
    return data
  },
  async (error) => {
    // 所有的接口响应失败都必须先执行这里
    const { response, status } = error
    if (status === 401) {
      // token 过期
      try {
        if (relogin.show) return
        relogin.show = true
        // 询问
        await ElMessageBox.confirm(
          '登录状态已过期,您可以继续留在当前页或重新登录',
          '系统提示',
          {
            confirmButtonText: '重新登录',
            cancelButtonText: '取消',
            type: 'warning'
          }
        )
        // 清空token和用户信息
        const userStore = useUserStore()
        userStore.logoutAction()
        // 跳转至登录页
        router.push(
          `/login?redirectUrl=${router.currentRoute.value.path}`
        )
        return Promise.reject(new Error('token过期'))
      } catch (e) {
      } finally {
        relogin.show = false
      }
    } else {
      const { code, msg } = response.data
      // 统一的错误提示
      ElMessage.error(msg)

      // 返回失败态的Promise实例，并携带错误信息
      return Promise.reject({
        code,
        msg
      })
    }
  }
)
// 导出自定义请求函数(url是接口地址(因为基本ip地址已经封装，只需接口地址再拼接即可)、请求类型、数据、参数、请求头)
export default ({ url, method, data, params, header }) => {
  return instance({
    url,
    method,
    data,
    params,
    header
  })
}
